package com.ddwl.user.service;

import cn.hutool.core.util.StrUtil;
import com.ddwl.common.feign.api.GateApi;
import com.ddwl.common.util.BeanConverUtils;
import com.ddwl.common.util.WeChatMessageUtil;
import com.ddwl.schema.vo.gate.wechat.WechatUserInfoListVo;
import com.ddwl.schema.vo.gate.wechat.WechatUserInfoVo;
import com.ddwl.user.dao.WxUserInfoDao;
import com.ddwl.user.model.WxUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author hemiaojun
 * @Date 2021/6/11 9:52
 */
@Slf4j
@Service
public class WxUserInfoService {

    @Resource
    private WxUserInfoDao wxUserInfoDao;
    @Resource
    private GateApi gateApi;


    public void syncWxUserInfo() {
        ((WxUserInfoService) AopContext.currentProxy()).recursionSaveWxUserInfo(null);
    }

    @Async
    public void recursionSaveWxUserInfo(String nextOpenId){
        WechatUserInfoListVo wxUserInfoListVo = gateApi.batchGetWxUserInfo(nextOpenId).getResult();
        if (StrUtil.isNotEmpty(wxUserInfoListVo.getNext_openid())) {
            saveWxUserInfo(wxUserInfoListVo.getUser_info_list());
            recursionSaveWxUserInfo(wxUserInfoListVo.getNext_openid());
        }
    }

    private void saveWxUserInfo(List<WechatUserInfoVo> userInfoList){
        if (!CollectionUtils.isEmpty(userInfoList)) {
            List<String> openIds = userInfoList.stream().map(WechatUserInfoVo::getOpenid).collect(Collectors.toList());
            List<WxUserInfo> wxUserInfoList = wxUserInfoDao.listByOpenIds(openIds);
            List<WxUserInfo> insertList = new ArrayList<>();
            userInfoList.forEach(wuiVo -> {
                WxUserInfo userInfo = wxUserInfoList.stream().filter(wxUserInfo -> wuiVo.getOpenid().equals(wxUserInfo.getOpenid())).findFirst().orElse(null);
                if (null != userInfo) {
                    BeanUtils.copyProperties(wuiVo, userInfo,"id");
                    userInfo.setSubscribeTime(wuiVo.getSubscribe_time());
                    userInfo.setQrScene(wuiVo.getQr_scene());
                    userInfo.setSubscribeScene(wuiVo.getSubscribe_scene());
                    userInfo.setQrSceneStr(wuiVo.getQr_scene_str());
                }else{
                    WxUserInfo entity = BeanConverUtils.convertBean(wuiVo, WxUserInfo.class);
                    entity.setSubscribeTime(wuiVo.getSubscribe_time());
                    entity.setQrScene(wuiVo.getQr_scene());
                    entity.setSubscribeScene(wuiVo.getSubscribe_scene());
                    entity.setQrSceneStr(wuiVo.getQr_scene_str());
                    insertList.add(entity);
                }
            });
            if (!CollectionUtils.isEmpty(insertList)) {
                wxUserInfoDao.insertList(insertList);
            }
            if (!CollectionUtils.isEmpty(wxUserInfoList)) {
                wxUserInfoDao.updateList(wxUserInfoList);
            }
        }
    }

    public String processNotify(HttpServletRequest request, HttpServletResponse response){
        ((WxUserInfoService) AopContext.currentProxy()).doProcessNotify(request, response);
        return "success";
    }

    @Async
    public void doProcessNotify(HttpServletRequest request, HttpServletResponse response){
        try {
            Map<String, String> requestMap = WeChatMessageUtil.parseXml(request, response);
            // 消息类型
            String msgType = requestMap.get("MsgType");
            String eventType = requestMap.get("Event");
            if (WeChatMessageUtil.REQ_MESSAGE_TYPE_EVENT.equals(msgType)) {
                // 发送方帐号（open_id）
                String fromUserName = requestMap.get("FromUserName");
                if (WeChatMessageUtil.EVENT_TYPE_SUBSCRIBE.equals(eventType)) {
                    WechatUserInfoVo result = gateApi.getWechatUserInfo(fromUserName).getResult();
                    WxUserInfo userInfo = BeanConverUtils.convertBean(result, WxUserInfo.class);
                    userInfo.setSubscribeTime(result.getSubscribe_time());
                    userInfo.setQrScene(result.getQr_scene());
                    userInfo.setSubscribeScene(result.getSubscribe_scene());
                    userInfo.setQrSceneStr(result.getQr_scene_str());
                    wxUserInfoDao.insert(userInfo);
                }
                if (WeChatMessageUtil.EVENT_TYPE_UNSUBSCRIBE.equals(eventType)) {
                    wxUserInfoDao.deleteByOpenId(fromUserName);
                }
            }
        } catch (Exception e) {
            log.error("处理微信通知事件出错",e);
        }
    }

    public String getOpenIdByUnionId(String unionId) {
        WxUserInfo entity = new WxUserInfo();
        entity.setUnionid(unionId);
        WxUserInfo userInfo = wxUserInfoDao.selectOne(entity);
        if (null != userInfo && StrUtil.isNotEmpty(userInfo.getOpenid())) {
            return userInfo.getOpenid();
        }
        return null;
    }
}
